package cc.telecomdigital.tdstock.trading.Tools;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;

import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.trading.Common.Trade_AppConstant;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;

public class Trade_StockFunctionTools
{
	/** Input a drawable image ID and will use the resource to get the image **/
	public static byte[] GetBytesofDrawableImage(Resources iResCont, int iResID)
	{
		Bitmap bmImage = BitmapFactory.decodeResource(iResCont, iResID);
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		// Middle parameter is quality, but since PNG is loss less, it doesn't
		// matter
		bmImage.compress(CompressFormat.PNG, 0, outputStream);
		return outputStream.toByteArray();
	}

	/** Create a bitmap with a binary array data **/
	public static Bitmap GetDrawableImageFromBytes(byte[] iByteContent)
	{
		if ((iByteContent == null) || (iByteContent.length == 0))
			return null;

		return BitmapFactory.decodeByteArray(iByteContent, 0,
				iByteContent.length);
	}

	/** Validate the choosen value of price, quantity and stepVolume of a stock
	    This is to check the spread price for a stock around certain value.
	    The iQuantity is to check whether it is a factor of the step volume  **/
	public static boolean ValidateStockTrade(String iPrice, String iQuantity,
								String iStepVolume)
	{
		BigDecimal tmpValue, tmpValue2;
		BigDecimal[] testValue;
		String spreadPrice;

		// check each text entry
		if ((iQuantity == null) || (iQuantity.length() == 0))
			return false;

		if (iQuantity.equals("0"))
			return false;

		if ((iPrice == null) || (iPrice.length() == 0))
			return false;

		// Check if the quantity is a factor of the step volume
		tmpValue = new BigDecimal(iQuantity);
		tmpValue2 = new BigDecimal(iStepVolume);
		testValue = tmpValue.divideAndRemainder(tmpValue2);
		if (testValue[1].compareTo(new BigDecimal("0")) >= 1)
			return false;

		// Check if the request price is in a valid format
		tmpValue = new BigDecimal(iPrice);
		if (tmpValue.compareTo(new BigDecimal("0.00")) <= 0)
			return false;

//Andy, will not check whether we need to see the price		
//		// Try to obtain the spread price
//		spreadPrice = GetStockPriceSpread(iPrice);
//		tmpValue = new BigDecimal(iPrice);
//		tmpValue2 = new BigDecimal(spreadPrice);
//		testValue = tmpValue.divideAndRemainder(tmpValue2);
//		if (testValue[1].compareTo(new BigDecimal("0")) >= 1)
//			return false;
	
		if (Trade_StockFunctionTools.IsStockPriceValid(iPrice,
				Trade_AppConstant.priceValueStringWithDec) == false)
			return false;

		return true;
	}

	/** Check whether the input is a valid stock price.  This is to look at
	    the decimal place after the value **/
	public static boolean IsStockPriceValid(String iStockPrice,
			int iMaxCharacter)
	{
		int valueLen, subLen;
		String valueString, deciString;

		iStockPrice = StringCorrection(iStockPrice);

		valueString = iStockPrice.replace(",", "");
		valueLen = valueString.lastIndexOf(".");
		if (valueLen == -1)
			return true;

		deciString = valueString.substring(valueLen, valueString.length());
		valueString = valueString.substring(0, valueLen);
		subLen = deciString.length();
		if (valueString.startsWith("0") && (valueString.length() > 1))
			return false;

		if ((valueLen + subLen) > iMaxCharacter)
			return false;

		return true;
	}

	/** Stock Price formating for display
	    Formatted String means 5,123,123 (9 char) **/
	public static String ConvertFormatUnitFromString(String iInString,
			int iMaxCharacter)
	{
		int valueLen;
		String newString, formatedString;
		String valueString;

		iInString = StringCorrection(iInString);

		iInString = iInString.replace(",", "");
		// Consider we have the new format
		formatedString = AddFormatToThousand(iInString);
		if (formatedString.length() <= iMaxCharacter)
			return formatedString;

		// If character exceed the limit we might need to trim to the proper
		// setting
		valueLen = iInString.lastIndexOf(".");
		if (valueLen != -1)
			valueString = iInString.substring(0, iInString.length());
		else
		{
			valueString = iInString;
			valueLen = valueString.length();
		}

		// we have fail and we can not do much
		if (valueLen <= 3)
			return iInString;

		newString = valueString;
		// our formating happens, we would forget about the decimal
		try
		{
			int value, count;

			// Count number of digit it has
			count = newString.length() / 3;
			value = newString.length() % 3;

			if (value == 0)
			{
				--count;
				value = 3;
			}

			if (count == 0)
			{

			}
			else if (count == 1)
			{
				newString = newString.substring(0, value);
				newString = "> " + newString + "K";
			}
			else if (count == 2)
			{
				newString = newString.substring(0, value);
				newString = "> " + newString + "M";
			}
			else if (count == 3)
			{
				newString = newString.substring(0, value);
				newString = "> " + newString + "B";
			}
			else if (count > 3)
			{
				value = newString.length() - 9;
				newString = newString.substring(0, value);
				newString = "> " + AddFormatToThousand(newString) + "B";
			}
			else
			{
				// UnDefine
				return iInString;
			}
		}
		catch (Exception ex)
		{
			newString = iInString;
			TDStockLog.e("StockFunctionTools",
					"ConvertFormatUnitFromString: " + ex.toString());
		}

		return newString;
	}

	/** Stock Price formatting, make closest to the cents value **/
	static public String AutoFormatPriceToCents(String inString)
	{
		int valueLen, subLen;
		String deciString, valueString;

		inString = StringCorrection(inString);

		// Bye if there are no decimal exist
		valueLen = inString.lastIndexOf(".");
		if (valueLen == -1)
			return inString + ".00";

		deciString = inString.substring(valueLen, inString.length());
		valueString = inString.substring(0, valueLen);
		subLen = deciString.length();
		// Now count how many 0 will we put at the back
		int index;

		for (index = subLen; index < 3; index++)
			deciString += "0";

		return valueString + deciString;
	}

	/** To satisfy the Stock Price format, it places extra zero after decimal to make
	    a valid 5 digit value display **/
	static public String AutoFillInDecimal(String inString,
			int iTotalWithDecimal)
	{
		int valueLen, subLen, requireLength, index;
		String deciString, valueString;
		String frontString, newString;

		inString = StringCorrection(inString);
		if ((inString == null) || (inString.length() == 0))
			return inString;

		// Trim the pos/neg sign, usually we do not have
		frontString = "";
		if (inString.substring(0, 1).equals("-"))
		{
			frontString = "-";
			inString = inString.substring(1, inString.length());
		}
		else if (inString.substring(0, 1).equals("+"))
		{
			frontString = "+";
			inString = inString.substring(1, inString.length());
		}

		newString = inString.replace(",", "");

		// Bye if there are no decimal exist
		valueLen = newString.lastIndexOf(".");
		if (valueLen == -1)
		{
			valueLen = newString.length();
			// Then we count whether we need .00
			if (valueLen > 4)
				return frontString + inString;

			requireLength = iTotalWithDecimal - valueLen - 1;
			deciString = ".";
			for (index = 0; index < requireLength; index++)
				deciString += "0";

			return frontString + inString + deciString;
		}

		deciString = inString.substring(valueLen, inString.length());
		valueString = inString.substring(0, valueLen);
		subLen = deciString.length();

		if (valueLen >= iTotalWithDecimal)
			return valueString;

		requireLength = iTotalWithDecimal - valueLen;
		if (subLen >= requireLength)
		{
			deciString = deciString.substring(0, requireLength);
			return frontString + valueString + deciString;
		}

		// end with a decimal
		if ((requireLength == 1) && (subLen == 1))
			return frontString + valueString;

		// Now count how many 0 will we put at the back
		for (index = subLen; index < requireLength; index++)
			deciString += "0";

		return frontString + valueString + deciString;
	}

	/** Place , for price over particular limit **/
	static public String AddFormatToThousand(String inString)
	{
		int length, first, second;
		String newString, subString, valueString;

		inString = StringCorrection(inString);

		// Take the decimal away for awhile
		inString = inString.replace(",", "");
		first = inString.lastIndexOf(".");
		if (first != -1)
		{
			valueString = inString.substring(0, first);
			subString = inString.substring(first, inString.length());
			// If the value is greater than thousand and the extra partial
			// cents can be trimmed
			if ((subString.length() == 4) && (valueString.length() > 3))
			{
				String testString;
				// Kill the extra zero, if the sum is too small
				testString = subString.substring(3, 4);
				if (testString.equals("0"))
					subString = subString.substring(0, 3);
			}
		}
		else
		{
			subString = "";
			valueString = inString;
		}

		length = valueString.length();
		second = length / 3;
		if (second == 0)
			return valueString + subString;

		first = length % 3;
		if (first == 0)
		{
			--second;
			first = 3;
		}

		// we will insert the ,
		int index, lenStart;

		newString = valueString;
		newString = newString.substring(0, first);
		lenStart = first;
		for (index = 0; index < second; index++, lenStart += 3)
		{
			newString += ",";
			newString += inString.substring(lenStart, lenStart + 3);
		}

		if (subString != null)
			newString += subString;

		return newString;
	}

	/** iValue1 is usually price, iValue2 is usually Quantity
	    return iVallue1 * iValue2 **/
	public static String CalculateProductInPrice(String iValue1, String iValue2)
	{
		BigDecimal value;

		iValue1 = StringCorrection(iValue1);
		iValue2 = StringCorrection(iValue2);

		if ((iValue1 == null) || (iValue2 == null))
			return "0.00";

		if ((iValue1.length() == 0) || (iValue2.length() == 0))
			return "0.00";

		// in case there are formatting
		iValue1 = iValue1.replace(",", "");
		iValue2 = iValue2.replace(",", "");

		if (iValue2.equals("0") || iValue1.equals("0"))
			return "0.00";

		value = new BigDecimal(iValue1);
		value = value.multiply(new BigDecimal(iValue2)).stripTrailingZeros();
		return value.toPlainString();
	}

	/** retun iValue1 + iValue2 **/
	public static String CalculateSumInPrice(String iValue1, String iValue2)
	{
		BigDecimal value;

		iValue1 = StringCorrection(iValue1);
		iValue2 = StringCorrection(iValue2);

		if ((iValue1 == null) || (iValue1.length() == 0))
		{
			if ((iValue2 == null) || (iValue2.length() == 0))
				return "0.00";

			return iValue2;
		}

		if ((iValue2 == null) || (iValue2.length() == 0))
		{
			if ((iValue1 == null) || (iValue1.length() == 0))
				return "0.00";

			return iValue1;
		}

		// in case there are formatting
		iValue1 = iValue1.replace(",", "");
		iValue2 = iValue2.replace(",", "");

		value = new BigDecimal(iValue1);
		value = value.add(new BigDecimal(iValue2)).stripTrailingZeros();
		return value.toPlainString();
	}

	/** return iValue1 - iValue2 **/
	public static String CalculateDiffInPrice(String iValue1, String iValue2)
	{
		BigDecimal value;

		iValue1 = StringCorrection(iValue1);
		iValue2 = StringCorrection(iValue2);

		if ((iValue1 == null) || (iValue1.length() == 0))
		{
			if ((iValue2 == null) || (iValue2.length() == 0))
				return "0.00";

			if (iValue2.startsWith("-"))
				iValue2 = iValue2.substring(1, iValue2.length());
			else
				iValue2 = "-" + iValue2;
			return iValue2;
		}

		if ((iValue2 == null) || (iValue2.length() == 0))
		{
			if ((iValue1 == null) || (iValue1.length() == 0))
				return "0.00";

			return iValue1;
		}

		// in case there are formatting
		iValue1 = iValue1.replace(",", "");
		iValue2 = iValue2.replace(",", "");

		value = new BigDecimal(iValue1);
		value = value.subtract(new BigDecimal(iValue2)).stripTrailingZeros();
		return value.toPlainString();
	}

	/** return iValue1/iValue2 **/
	public static String CalculateQuotientInPrice(String iValue1,
			String iValue2)
	{
		return CalculateQuotientInPrice(iValue1, iValue2, 5);
	}

	/** return iValue1/iValue2 **/
	public static String CalculateQuotientInPrice(String iValue1,
			String iValue2, int iPrecision)
	{
		BigDecimal value;

		iValue1 = StringCorrection(iValue1);
		iValue2 = StringCorrection(iValue2);

		if ((iValue1 == null) || (iValue2 == null))
			return "0.00";

		if ((iValue1.length() == 0) || (iValue2.length() == 0))
			return "0.00";

		// in case there are formatting
		iValue1 = iValue1.replace(",", "");
		iValue2 = iValue2.replace(",", "");

		if (iValue2.equals("0") || iValue1.equals("0"))
			return "0.00";

		value = new BigDecimal(iValue1);
		value = value.divide(new BigDecimal(iValue2), iPrecision,
				RoundingMode.HALF_UP).stripTrailingZeros();
		return value.toPlainString();
	}

	/** Base on the HKEC rule, price spread change after certain amount
	    is reached.  This return a stepChange for a particular price **/
	public static String GetStockPriceSpread(String iPrice)
	{
		BigDecimal deciValue;

		iPrice = StringCorrection(iPrice);

		// Send the lowest option
		if (iPrice == null || iPrice.length() == 0)
			return "0.001";

		// Now base on the value to find the closest one
		iPrice = iPrice.replace(",", "");
		iPrice = iPrice.replace("-", "");
		// Find if there are any decimal
		deciValue = new BigDecimal(iPrice);
		deciValue = deciValue.setScale(4, RoundingMode.UNNECESSARY);
		if (deciValue.compareTo(new BigDecimal(5000)) >= 0)
			return "5";
		if (deciValue.compareTo(new BigDecimal(2000)) >= 0)
			return "2";
		if (deciValue.compareTo(new BigDecimal(1000)) >= 0)
			return "1";
		if (deciValue.compareTo(new BigDecimal(500)) >= 0)
			return "0.5";
		if (deciValue.compareTo(new BigDecimal(200)) >= 0)
			return "0.2";
		if (deciValue.compareTo(new BigDecimal(100)) >= 0)
			return "0.1";
		if (deciValue.compareTo(new BigDecimal(20)) >= 0)
			return "0.05";
		if (deciValue.compareTo(new BigDecimal(10)) >= 0)
			return "0.02";
		if (deciValue.compareTo(new BigDecimal(0.5)) >= 0)
			return "0.01";
		if (deciValue.compareTo(new BigDecimal(0.25)) >= 0)
			return "0.005";
		// if (deciValue.compareTo(new BigDecimal(0.01)) >= 0)
		// return "0.001";
		return "0.001";
	}

	/** Remove extra space from the String **/
	static private String StringCorrection(String iValue)
	{
		if ((iValue != null) && (iValue.length() > 0))
			iValue = iValue.trim();

		return iValue;
	}
	
	static final private int StockCodeFixLen = 5;
	static public String FormatFullStockCode(String iCode)
	{
		int length;
		
		iCode = iCode.trim();
		length = iCode.length();
		if (length >= StockCodeFixLen)
			return iCode;
			
		String header;
		int    index;
		
		header = "";
		
		for(index = 0; index < StockCodeFixLen-length; index++)
			header += "0";
		
		return header+iCode;
	}
	
	static public String RemoveStockCodeFormat(String iCode) 
	{
		int length;
				
		iCode = iCode.trim();
		length = iCode.length();
		if (length  < 1)
			return iCode;
		
		return iCode.replaceFirst("^0+(?!$)", "");
	}	
}
